#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>


#define STR1(S) #S
#define STR(S)  STR1(S)  //将宏定义转化为字符串

//#define __DEBUG
#ifdef __DEBUG
	#define DEBUG(...) printf(__VA_ARGS__);printf("______Line:%d\n",__LINE__)
#else
	#define DEBUG(...)
#endif


#define    VERSION   1.0
#define  FILE_FLAG	 "/home/pi/remind/ZYX_REMIND_FLAG"  
#define  USER_CONF   "/home/pi/remind/usr.conf" 
#define  TMP 		 "/home/pi/remind/tmp" 
#define  SMS_ACCOUNT "/home/pi/remind/SMS_ACCOUNT.txt" 
//这里的路径就是标识文件的路径，文件名可以随便起

typedef struct Event
{
	char title[100];
	char time[20];
	int  num; //编号
	
}Event;  


int main(int argc,char *argv[])
{
	int line=1;
	int ch,fch;
    char cmd[30]={0}; //存放system系统调用指令
	char buffer[10]; //存放读取的进程号
	Event event={0,0};
	int et_rule=0; //规则判断
	int fd = -1;
	char account_buffer[100]={0};//存储账户信息
	char *env[20]={"via=msg",NULL};  //环境变量
	FILE *fpointer;
	
    //打印欢迎消息和帮助
	printf("Welcome to \'remind\'--ver-%s\n",STR(VERSION));  //将宏定义转化为字符串
	printf("Remind usage is listed as follows:\n");
	printf("remind [option]... [parameters]...\n");
	printf("-t -e 	add a time and event to remind\n");
	printf("-l 		list recorded schedule\n");
	printf("-d 		delete a recorded item is schedule\n");
	printf("-q 		quit remind\n");
	printf("-s 		start remind\n");
	//读取当前SMS_ACCOUNT
	FILE *fp_SMS_Account=fopen(SMS_ACCOUNT, "r");
	fgets(account_buffer,sizeof(account_buffer),fp_SMS_Account);
    fclose(fp_SMS_Account);
	char *token = strtok(account_buffer,"=");
	token = strtok(NULL,"=");
	printf("Attention:The current SMS&SMTP host is %sYou can redirect message to another account by following steps:\n",token);
	printf("1. remind -q \n");
	printf("2. edit ~/remind/SMS_ACCOUNT.txt and save\n");
	printf("3. remind -s \n");
	//命令行参数提取
	while ((ch = getopt(argc, argv, "t:d:e:qls:")) != -1)  
       {
		   //DEBUG("optind: %d", optind);
           switch (ch) 
        {
			   case 's': //开启任务,程序执行之初，先去判断文件是否存在					   
					fd = open(FILE_FLAG, O_RDWR | O_TRUNC | O_CREAT | O_EXCL, 0664);
					if (fd < 0)
					{
						if (errno == EEXIST)
						{
							printf("The process is runninng now,do not repeat it!\n");							
							return -1;
						}
					}
					//判断使用哪种方式进行通知，参数为msg/mail/mm
					 if(!strcmp(optarg,"msg"))
					 {
						 env[0]="via=msg";
					 }
					 else if(!strcmp(optarg,"mail"))
					 {
						 env[0]="via=mail";
					 }
					 else if(!strcmp(optarg,"mm"))
					 {
						 env[0]="via=mm";
					 }
					 else
					 {
						 printf("-s para should be \"msg\" \"mail!\" or \"mm\" \n");
						 return -1;
					 }
					 
				     if(execle("/usr/bin/python3","/usr/bin/python3","/home/pi/remind/RUN.py",NULL,env)==-1)
					 {
						 printf("error occur:%s\n",strerror(errno));
						 return -1;
					 }				    		   
				     break;			
               case 'q': //先查找是否有标志位文件，若有则读取进程号并kill,若无则给出提示信息
					
						if(access(TMP,F_OK)!=-1)  //文件存在
						{
							//查找进程							
							FILE *fp=fopen(TMP, "r"); 
							fgets(buffer,sizeof(buffer),fp); //获得子进程的输出结果
							//printf("%s\n",buffer); 
							int pid_num=atoi(buffer);
																				
							//kill进程
							kill((pid_t)pid_num,SIGINT);						 
							fclose(fp);
							return 0;					
						}					
						else
						{
							printf("no remind running\n");						
							return -1;
						}					
                       break;
               case 'e': //添加待提醒事件(天气，备忘事件等)
                       DEBUG("HAVE option: -e"); 
                       DEBUG("The argument of -e is %s", optarg);
					   stpcpy(event.title,optarg);
					   et_rule++;
                       break;
               case 't': //添加一个提醒点
                       DEBUG("HAVE option: -t");
                       DEBUG("The argument of -t is %s", optarg);
					   strcpy(event.time,optarg);
					   et_rule++;
                       break;
			   case 'd':  //删除一个提醒点,参数为-l下的标号
                       DEBUG("HAVE option: -d");
                       DEBUG("The argument of -d is %s", optarg);
					   sprintf(cmd,"sed -i \'%sd\' %s",optarg,USER_CONF); //-i直接修改文件内容
					   system(cmd);					   
				       if(access(TMP,F_OK)!=-1)  
					   {
						 FILE *fp_d=fopen(TMP, "r"); 
					     fgets(buffer,sizeof(buffer),fp_d); //获得子进程的pid
					     int pid_d=atoi(buffer);	
						 //发送信号给子进程
						 kill((pid_t)pid_d,SIGUSR1);						 
						 fclose(fp_d);
					   }
					   
                       break;	
			   case 'l': //查看所有待提醒的事件及时间
			           printf("Recorded Schedule List-----------------\n");
					   //读取文件
					   printf("1.");
					   fpointer=fopen(USER_CONF,"a+"); //打开配置文件，读取和追加模式
					   while((fch=fgetc(fpointer))!=EOF)
					   {					  
						  fputc(fch,stdout); //这里是输出到屏幕 
						  if(fch=='\n')
						   {
							  if(fgetc(fpointer)!=EOF)
							  {
								  fseek(fpointer,-1,SEEK_CUR);//指针偏移
								  line++;
							      printf("%d.",line);
							  }							  
						   }
					   }	     
					   printf("---------------------------------------\n");
					   fclose(fpointer);  
					   break;
               case '?'://无效的命令
                       DEBUG("Undefined option: %c\n",(char)optopt);
                       break;
               }
       }
	      
	  //命令行参数设置合法性分析，并写入配置文件
	  if(et_rule==2) //当-t -e同时存在时才写入配置文件
	  {
		if(access(TMP,F_OK)!=-1)  //文件存在，已有运行的实例时
		{
			DEBUG("event.title=%s,event.time=%s\n",event.title,event.time);
			fpointer=fopen(USER_CONF,"a+"); //打开配置文件，读取和追加模式
			if(!fpointer)
			{
				printf("can not open file\n");
				return -1;
			}
		   fprintf(fpointer,"%s ## %s\n",event.title,event.time); 
		   fclose(fpointer);  
		  //通过文件的方式获取子进程的pid
		  //查找进程							
			FILE *fp=fopen(TMP, "r"); 
			fgets(buffer,sizeof(buffer),fp); //获得子进程的pid
			int pid=atoi(buffer);													
			//发送信号给子进程
			kill((pid_t)pid,SIGUSR1);						 
			fclose(fp);
		}
		else
		{
			fpointer=fopen(USER_CONF,"a+"); //打开配置文件，读取和追加模式
			if(!fpointer)
			{
				printf("can not open file\n");
				return -1;
			}
		   fprintf(fpointer,"%s ## %s\n",event.title,event.time); 
		   fclose(fpointer);  
		}
				 
	  }
	  else if(et_rule==1)
	  {
		  printf("Invalid single -t or -e\n");
		  return -1;
	  }
	  else
	  {
		  printf("exit\n");
	  }
	       
	   return 0;
	
}